#![no_std]
#![feature(abi_efiapi)]

#[cfg(test)]
extern crate std;

use core::ffi::c_void;

use system_table::EfiSystemTable;

pub mod status_code;
pub mod protocol;
pub mod services;
pub mod system_table;
pub mod gpt;

pub type EfiHandle = *mut c_void;
pub type Char16 = u16;
pub use status_code::EfiStatus;

pub type EfiImageEntryPoint = fn(image_handle:EfiHandle, system_table:*const EfiSystemTable)->EfiStatus;
#[repr(C)]
pub struct EfiGuid {
    /// 64-bit 时间戳的低字段。
    pub time_low: u32,
    /// 64-bit 时间戳的中字段。
    pub time_mid: u16,
    /// 64-bit 时间戳的高字段，该字段会和版本号复用。
    pub time_high_and_version: u16,
    /// 时钟序列的高字段，该字段会和其他变种复用。a
    pub clock_seq_high_and_reserved: u8,
    /// 时钟序列的低字段。
    pub clock_seq_low: u8,
    /// 节点标识符。可以是网卡上的 IEEE 802 地址。
    /// 如果系统上没有网卡，则可以使用带有加密质量的随机数。
    pub node: [u8; 6],
}

#[macro_export]
/// 像 C 一样初始化 Guid 结构体，一般只是为了方便从 UEFI Spec 上直接拷贝 GUID 宏。
/// ```
/// pub pub const GUID: Guid =
/// guid_struct! {0x387477c1,0x69c7,0x11d2, {0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b}};
/// ```
macro_rules! guid_struct {
    ($time_low:literal, $time_mid: literal, $time_high_and_version:literal, 
        {
            $clock_seq_high_and_reserved:literal, $clock_seq_low:literal, 
            $node0:literal, $node1:literal, $node2:literal, $node3:literal, $node4:literal, $node5:literal
        }
    ) => {
        EfiGuid {
            time_low: $time_low,
            time_mid: $time_mid,
            time_high_and_version: $time_high_and_version,
            clock_seq_high_and_reserved: $clock_seq_high_and_reserved,
            clock_seq_low: $clock_seq_low,
            node: [$node0, $node1, $node2, $node3, $node4, $node5],
        }
    };
}
